#include "cdir.h"

int user_init(char *username, MYSQL *mysql, my_stack *st){
    // 查询用户是否存在
    char sql[512];
    snprintf(sql, sizeof(sql),
                "select id from virtual_directory where path = '/' and user_name = '%s' and is_deleted = 0",
                username);
    MYSQL_ROW rowArr;
    int qret = query_database(sql, mysql, &rowArr);
    if(qret == 0){
        // printf("Root directory already exists for user %s\n", username);
        if(st->stack_size == 0){
            //printf("user_init: push root id = %s\n", rowArr[0]);
            stack_push(st, atoi(rowArr[0]));
        }
        return 0;
    }

    // 表中插入用户数据
    char sql_user[512];
    snprintf(sql_user, sizeof(sql_user),
             "insert into virtual_directory" 
             "(file_name,user_name,parent_id,type,path,is_deleted)"
             "values ('/','%s','-1','d','/','0')",
             username);
    int iret = mysql_query(mysql, sql_user);
    if(iret != 0){
        // printf("Error: Failed to create user %s\n", username);
        return -1;
    }

    // 获取插入的id
    char sql_id[512];
    snprintf(sql_id, sizeof(sql_id),
             "select id from virtual_directory where file_name = '/' and user_name = '%s' and is_deleted = 0",
             username);
    MYSQL_ROW rowArr_id;
    int qret_id = query_database(sql_id, mysql, &rowArr_id);
    if(qret_id != 0){
        // printf("Error: Failed to get id for user %s\n", username);
        return -1;
    }
    stack_push(st, atoi(rowArr_id[0]));
    return 0;
}

int query_database(char *sql, MYSQL *mysql, MYSQL_ROW *rowArr){
    int qret = mysql_query(mysql, sql);  // 查表
    if(qret != 0){
        fprintf(stderr, "%s:%s\n", "mysql_query", mysql_error(mysql));
        return -1;
    }

    MYSQL_RES *result = mysql_store_result(mysql); // 取出表格
    if(result == NULL)  return -1; //查询结果为空

    *rowArr = mysql_fetch_row(result); // 字符串数组
    if (rowArr == NULL || rowArr[0] == NULL) {  // 获取行失败 or rowArr 第一个字段为NULL
        mysql_free_result(result);
        return -1;   
    }

    mysql_free_result(result);
    return 0;
}

int validate_directory(char *username, MYSQL *mysql, const char *dir_path){
    char sql[512];
    // 简单处理，存在SQL注入风险，拖库攻击
    snprintf(sql, sizeof(sql),
             "select * from virtual_directory where type = 'd' and path = '%s' and user_name = '%s' and is_deleted = 0",
             dir_path, username);
    // 执行查询操作
    MYSQL_ROW rowArr;
    int ret = query_database(sql, mysql, &rowArr);

    return ret;
}

int get_dire_path(MYSQL *mysql, my_stack *st, char *cur_path){
    char sql[512];
    if (st->stack_top == NULL) {
        fprintf(stderr, "Error: stack_top is NULL in get_dire_path\n");
        return -1;
    }
    snprintf(sql, sizeof(sql),
             "select path from virtual_directory where id = %d",
             st->stack_top->id);
    MYSQL_ROW rowArr;
    int qret = query_database(sql, mysql, &rowArr);
    if(qret != 0){
        // printf("query_database false");
        return -1;
    }
    /* memcpy(cur_path, rowArr[0], strlen(rowArr[0])); */
    strcpy(cur_path, rowArr[0]);
    return 0;
}

int push_dire(char *username, MYSQL *mysql, my_stack *st, char *token){
    char sql[1024];

    // 获取当前目录的路径，用于构建子目录的完整路径
    char current_path[256] = {0};
    get_dire_path(mysql, st, current_path);
    // printf("push_dire current_path = %s\n", current_path);

    // 构建目标目录的完整路径
    char target_path[512] = {0};
    if(strcmp(current_path, "/") == 0) {
        snprintf(target_path, sizeof(target_path), "/%s", token);
    } else {
        snprintf(target_path, sizeof(target_path), "%s/%s", current_path, token);
    }

    snprintf(sql, sizeof(sql),
             "select id from virtual_directory where type = 'd' and path = '%s' and user_name = '%s' and is_deleted = 0",
             target_path, username);

    MYSQL_ROW rowArr;
    int qret = query_database(sql, mysql, &rowArr);
    if(qret != 0){
        return -1;
    }
    stack_push(st, atoi(rowArr[0]));
    return 0;
}

int split_path(char *username, MYSQL *mysql, my_stack *st, char *path){
    if(st->stack_size == 0){
        char token[] = "/";
        if(push_dire(username, mysql, st, token) != 0) {
            return -1;
        }
    }

    // 如果path只是"/"，直接返回成功
    if(strcmp(path, "/") == 0) {
        return 0;
    }

    char *saveptr;
    char *token = strtok_r(path, "/", &saveptr);
    while(token != NULL){
        // token == "."
        if(strcmp(token, ".") == 0){} // do nothing

        // token == ".."
        else if(strcmp(token, "..") == 0){
            if(st->stack_size > 1){
                stack_pop(st);
            }
        }
        // others
        else{
            int pret = push_dire(username, mysql, st, token);
            if(pret != 0){
                return -1;
            }
        }

        token = strtok_r(NULL, "/", &saveptr);
    }
    return 0;
}

int join_path(MYSQL *mysql, my_stack *st, char *path, char *join_path){
    // 1、获取当前目录路径join_path
    /* char cur_path[128] = {0}; */
    get_dire_path(mysql, st, join_path);

    // 2、join_path 与 path 与拼接
    if(path[0] != '/'){

        // 确保当前路径不以 '/' 结尾（除非是根目录）
        int len = strlen(join_path);
        if(len > 1 && join_path[len-1] == '/') {
            join_path[len-1] = '\0';  // 移除末尾的 '/'
        }

        if(strcmp(join_path, "/") != 0) {
            strcat(join_path, "/");
        }
        strcat(join_path, path);
    }else{
        strcpy(join_path, path);
    }

    // printf("拼接后的 join_path = %s\n", join_path);

    return 0;
}

int check_path(char *username, MYSQL *mysql, my_stack *st, char *union_path){
    // 处理cur_path
    my_stack st_tmp;
    stack_init(&st_tmp);
    user_init(username, mysql, &st_tmp);
    // stack_copy(&st_tmp, st);

    int sret = split_path(username, mysql, &st_tmp, union_path);
    if(sret != 0){
        stack_destroy(&st_tmp);
        return -1;
    }
    /* printf("st_tmp  = ------------\n"); */
    /* print_stack(st_tmp); */

    stack_destroy(st);
    stack_init(st);
    stack_copy(st, &st_tmp); 

    /* printf("st after copy = ------------\n"); */
    /* print_stack(*st); */

    stack_destroy(&st_tmp);
    return 0;
}

int handle_cd(char *username, MYSQL *mysql, my_stack *st, char *path, char *retpath){
    // 1、将 / 压栈
    // if(st->stack_size == 0){
    //     char token[] = "/";
    //     push_dire(username, mysql, st, token);
    // }

    // 2、处理路径
    char union_path[128] = {0};
    int jret = join_path(mysql, st, path, union_path); 
    if(jret != 0){
        return -1;
    }

    int cret = check_path(username, mysql, st, union_path);
    if(cret != 0){
        return -1;
    }
    
    get_dire_path(mysql, st, retpath);
    return 0;
}

int handle_mkdir(char *username, MYSQL *mysql, my_stack *st, char *path){
    char union_path[128] = {0};
    join_path(mysql, st, path, union_path);
    // printf("union_path = %s\n", union_path);

    // 获取创建的新目录名和父目录路径
    char *last_slash = strrchr(union_path, '/');
    // printf("last_slash = %s\n", last_slash);

    // 处理非新目录路径
    char parent_path[128] = {0};
    if (last_slash == union_path) {
        // 根目录
        strcpy(parent_path, "/");
    } else {
        size_t len = last_slash - union_path;
        strncpy(parent_path, union_path, len);
        parent_path[len] = '\0';
    }
    char *new_dir = strdup(last_slash + 1);
    // printf("new_dir = %s, parent_path = %s\n", new_dir, parent_path);

    // 判断路径是否存在
    my_stack st_tmp;
    stack_init(&st_tmp);
    user_init(username, mysql, &st_tmp);
    // stack_copy(&st_tmp, st);

    char *parent_path2 = strdup(parent_path);
    int cret = check_path(username, mysql, &st_tmp, parent_path);
    if(cret != 0){
        free(new_dir);
        return -1;
    }
    stack_destroy(&st_tmp);

    // 查找新目录是否已存在，获取is_deleted
    char sql[512];
    snprintf(sql, sizeof(sql),
             "select is_deleted, id from virtual_directory where user_name = '%s' and path = '%s'",
             username, union_path);
    MYSQL_ROW rowArr1;
    int qret1 = query_database(sql, mysql, &rowArr1);
    if(qret1 == 0){  // 目录已存在,且 is_deleted == 0
        if(atoi(rowArr1[0]) == 0) { free(new_dir); return 1; }

        // 修改 is_deleted = 0
        char sql2[512] = {0}; 
        snprintf(sql2, sizeof(sql2), 
                 "update virtual_directory set is_deleted = 0 where id = %d" ,
                 atoi(rowArr1[1]));
        int iret = mysql_query(mysql, sql2);
        free(new_dir);
        if(iret != 0){
            return -1;
        }
        return 0;
    }

    // 获取新建目录的parent_id
    char sql_query[512];
    snprintf(sql_query, sizeof(sql_query),
             "select id from virtual_directory where user_name = '%s' and path = '%s'",
             username, parent_path2);
    MYSQL_ROW rowArr;
    free(parent_path2);
    int qret = query_database(sql_query, mysql, &rowArr);
    if(qret != 0){
        free(new_dir);
        return -1;
    }
    // printf("mkdir: parent_id = %s\n", rowArr[0]);

    // 表中插入新目录
    char sql_insert[512] = {0}; 
    snprintf(sql_insert, sizeof(sql_insert), "insert into virtual_directory" 
             "(file_name,user_name,parent_id,type,path,is_deleted) values ('%s','%s','%d','d','%s','0')",
             new_dir, username, atoi(rowArr[0]), union_path);
    int iret = mysql_query(mysql, sql_insert);
    free(new_dir);
    if(iret != 0){
        return -1;
    }
    return 0;
}

int handle_rmdir(char *username, MYSQL *mysql, my_stack *st, char *path){
    char union_path[128] = {0};
    join_path(mysql, st, path, union_path);
    // printf("handle_rmdir: union_path = %s\n", union_path);

    // 判断路径是否存在
    my_stack st_tmp;
    stack_init(&st_tmp);
    user_init(username, mysql, &st_tmp);

    char parent_path[128] = {0};
    memcpy(parent_path, union_path, strlen(union_path));
    // printf("handle_rmdir: parent_path = %s\n", parent_path);

    int cret = check_path(username, mysql, &st_tmp, parent_path);
    if(cret != 0){
        // printf("handle_rmdir: check_path failed\n");
        return -1;
    }
    stack_destroy(&st_tmp);

    // 查找要删除的目录是否已存在，获取is_deleted
    char sql[512];
    snprintf(sql, sizeof(sql),
             "select is_deleted,id from virtual_directory where user_name = '%s' and path = '%s'",
             username, union_path);
    MYSQL_ROW rowArr1;
    int qret1 = query_database(sql, mysql, &rowArr1);
    if(qret1 != 0){
        return -1;  // 目录不存在
    }

    int dir_id = atoi(rowArr1[1]);
    printf("rmdir: is_deleted = %s, id = %d\n", rowArr1[0], dir_id);
    
    // 目录存在
    // is_deleted == 1
    if(atoi(rowArr1[0]) == 1) return -1; 

    // is_deleted == 0 子目录存在
    char sql_child[512];
    snprintf(sql_child, sizeof(sql_child),
             "select count(*) from virtual_directory where parent_id = %d and user_name = '%s' and is_deleted = 0",
             dir_id, username);
    MYSQL_ROW rowArr2;
    int qret2 = query_database(sql_child, mysql, &rowArr2);
    if(qret2 != 0){
        return -1; // 查询失败
    }
    if(atoi(rowArr2[0]) > 0){
        printf("rmdir: 有子目录\n");
        return -1; // 有子目录
    }

    // 修改 is_deleted
    char sql2[512] = {0}; 
    snprintf(sql2, sizeof(sql2), 
             "update virtual_directory set is_deleted = 1 where id = %d" ,
             dir_id);
    printf("rmdir: sql2 = %s\n", sql2);
    
    int iret = mysql_query(mysql, sql2);
    if(iret != 0){
        return -1;
    }
    printf("rmdir: 删除成功\n");

    return 0;
}
